package ee.mtiidla.tuk.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import ee.mtiidla.data.Event;
import ee.mtiidla.data.Session;
import ee.mtiidla.tuk.data.AgeGroupOrder;
import ee.mtiidla.tuk.data.RankingOrder;

/**
 * Created by Marko on 12.10.2014.
 */
@SuppressWarnings("unchecked")
public class MainFrame extends JFrame implements ListSelectionListener {

	public interface UICallback {

		public void onOpenLenexClick();

		public void onOpenTemplateClick();

		public void onReloadClick();

		public void onGenerateClick(List<Long> selectedEvents);

	}

	public UICallback mCallback;
	private JPanel mSessionsContainer;
	private JScrollPane mEventsContainer;

	private JCheckBox mRankingOrder;
	private JCheckBox mAgeGroupOrder;

	public MainFrame(String title, UICallback callback) throws HeadlessException {
		super(title);
		this.mCallback = callback;
	}

	public static MainFrame create(UICallback callback) {

		try {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}

		//1. Create the frame.
		MainFrame frame = new MainFrame("Autasustamine", callback);

		//2. Optional: What happens when the frame closes?
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		//3. Create components and put them in the frame.
		frame.addContent();
		//4. Size the frame.
		frame.pack();

		//5. Show it.
		frame.setVisible(true);

		return frame;
	}

	public RankingOrder getRankingOrder() {
		return mRankingOrder.isSelected() ? RankingOrder.WINNER_FIRST : RankingOrder.WINNER_LAST;
	}

	public AgeGroupOrder getAgeGroupOrder() {
		return mAgeGroupOrder.isSelected() ? AgeGroupOrder.YOUNGEST_LAST : AgeGroupOrder.YOUNGEST_FIRST;
	}

	public void addContent() {

		Container pane = getContentPane();

		final JPanel components = new JPanel(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		//Add buttons to experiment with Grid Layout
		JButton lenex = new JButton("Open Lenex");
		lenex.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				handleOpenLenexClick();
			}

		});
		components.add(lenex, c);
		c.gridx = 1;
		c.gridy = 0;
		JButton template = new JButton("Open HTML template");
		template.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				handleOpenTemplateClick();
			}
		});
		components.add(template, c);
		c.gridx = 0;
		c.gridy = 1;
		JButton reload = new JButton("Reload");
		reload.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				handleReloadClick();
			}
		});
		components.add(reload, c);
		c.gridx = 1;
		c.gridy = 1;
		JButton generate = new JButton("Generate");
		generate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				handleGenerateClick();
			}
		});
		components.add(generate, c);
		c.gridx = 0;
		c.gridy = 2;
		JLabel sessionsLabel = new JLabel("Sessions");
		sessionsLabel.setHorizontalAlignment(SwingConstants.CENTER);
		components.add(sessionsLabel, c);
		c.gridx = 1;
		c.gridy = 2;
		JLabel eventsLabel = new JLabel("Events");
		eventsLabel.setHorizontalAlignment(SwingConstants.CENTER);
		components.add(eventsLabel, c);

		for (Component component : components.getComponents()) {
			component.setPreferredSize(new Dimension(180, 30));
		}

		c.gridx = 0;
		c.gridy = 3;
		mSessionsContainer = new JPanel();
		mSessionsContainer.setPreferredSize(new Dimension(180, 200));
		components.add(mSessionsContainer, c);

		c.gridx = 1;
		c.gridy = 3;
		JPanel events = new JPanel();
		events.setLayout(new GridLayout(0, 1));
		mEventsContainer = new JScrollPane();
		mEventsContainer.getViewport().add(events);
		mEventsContainer.setPreferredSize(new Dimension(170, 190));
		components.add(mEventsContainer, c);

		c.gridx = 0;
		c.gridy = 4;
		mRankingOrder = new JCheckBox("Order winner first");
		components.add(mRankingOrder, c);

		c.gridx = 1;
		c.gridy = 4;
		mAgeGroupOrder = new JCheckBox("Order oldest first");
		components.add(mAgeGroupOrder, c);

		pane.add(components, BorderLayout.NORTH);
	}

	private void handleGenerateClick() {
		mCallback.onGenerateClick(getSelectedEvents());
	}

	private void handleReloadClick() {
		mCallback.onReloadClick();
	}

	private void handleOpenTemplateClick() {
		mCallback.onOpenTemplateClick();
	}

	private void handleOpenLenexClick() {
		mCallback.onOpenLenexClick();
	}

	public void setSessions(List<Session> sessions) {

		JList<Session> sessionList;
		if (mSessionsContainer.getComponentCount() == 0) {
			sessionList = new JList<Session>();
			sessionList.setPreferredSize(new Dimension(170, 190));
			sessionList.setModel(new DefaultListModel<Session>());
			sessionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			sessionList.addListSelectionListener(this);
			mSessionsContainer.add(sessionList);
		} else {
			sessionList = (JList<Session>) mSessionsContainer.getComponent(0);
		}

		DefaultListModel<Session> listModel = (DefaultListModel<Session>) sessionList.getModel();
		listModel.removeAllElements();

		for (Session session : sessions) {
			listModel.addElement(session);
		}

		sessionList.setSelectedIndex(0);
	}

	public void setEvents(List<Event> events) {

		JPanel eventsContainer = (JPanel) mEventsContainer.getViewport().getComponent(0);

		eventsContainer.removeAll();

		for (Event event : events) {
			JCheckBox checkBox = new JCheckBox(event.toString());
			checkBox.setName(String.valueOf(event.getEventId()));
			eventsContainer.add(checkBox);
		}

		eventsContainer.updateUI();

	}


	@Override
	public void valueChanged(ListSelectionEvent e) {
		if (!e.getValueIsAdjusting()) {

			JList<Session> sessionJList = (JList<Session>) e.getSource();

			if (sessionJList.getSelectedIndex() == -1) {

			} else {
				setEvents(sessionJList.getModel()
						.getElementAt(sessionJList.getSelectedIndex()).getEvents());
			}
		}
	}


	private List<Long> getSelectedEvents() {

		JPanel eventsContainer = (JPanel) mEventsContainer.getViewport().getComponent(0);

		List<Long> selectedEvents = new ArrayList<Long>();

		for (Component component : eventsContainer.getComponents()) {

			if (component instanceof JCheckBox) {
				if (((JCheckBox) component).isSelected()) {
					selectedEvents.add(Long.parseLong(component.getName()));
				}
			}

		}

		return selectedEvents;
	}
}
